﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NMoq.Core
{
    public class DefaultInterceptor:IInterceptor
    { 
        #region IInterceptor Members
        public event EventHandler<InterceptEventArgs> PreIntercept;
        public event EventHandler<InterceptEventArgs> AftIntercept;
        public event EventHandler<InterceptEventArgs> AftInvoked;

        public void Intercept(IInvocation invocation,IDataProvider dataProvider)
        {
            if (PreIntercept != null) 
                PreIntercept(this, new InterceptEventArgs(invocation, dataProvider));

            #region Intercept begin
            if (dataProvider != null)
            {
                DataProviderResult dataProviderResult = dataProvider.Read(invocation.GetMethodMessgeInfo());
                invocation.ReturnResult = dataProviderResult;
            }

            if (!invocation.ReturnResult.HasValue && (invocation.ActionAfterRead&InterceptorActionAfterRead.InvokeReal) != 0)
            { 
                object retValue = invocation.MethodCallMessage.MethodBase.Invoke(invocation.Target, invocation.MethodCallMessage.Args);
                invocation.ReturnResult.HasValue = true;
                invocation.ReturnResult.ReturnValue = retValue;                
            }

            if (dataProvider != null && invocation.ReturnResult.HasValue && (invocation.ActionAfterRead & InterceptorActionAfterRead.Write) != 0)
            {
                dataProvider.Write(invocation.GetMethodMessgeInfo(), invocation.ReturnResult.ReturnValue);
            }

            invocation.HasIntercepted = true;
            #endregion Intercept end

            if(AftIntercept !=null )
                AftIntercept(this, new InterceptEventArgs(invocation, dataProvider));
        }

        public void OnAftInvoked(IInvocation invocation, IDataProvider dataProvider)
        {
            if(AftInvoked != null )
                AftInvoked(this, new InterceptEventArgs(invocation, dataProvider));
        }
        #endregion 
    }
}
